﻿using Daphne.Modularity.Messaging;
using Daphne.Modularity.Storage;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Daphne.Modularity.UI
{
    /// <summary>
    /// Base class for view models
    /// </summary>
    public class ViewModelBase: INotifyPropertyChanged, ISaveRestore
    {
        /// <summary>
        /// Notify property event changed
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Unity DI Container
        /// </summary>
        [Dependency]
        protected IUnityContainer Unity
        { get; set;  }

        /// <summary>
        /// Messenger notification class
        /// </summary>
        [Dependency]
        protected IMessenger Messenger
        { get; set; }

        /// <summary>
        /// Raises notification of property changed
        /// </summary>
        protected void RaisePropertyChanged(string propertyName)
        {
            if(PropertyChanged != null)
            {
                PropertyChangedEventArgs args = new PropertyChangedEventArgs(propertyName);
                PropertyChanged(this, args);
            }
        }
        
        /// <summary>
        /// Raises notification of property changed
        /// </summary>
        protected void RaisePropertyChanged<T>(Expression<Func<T>> selectorExpression)
        {
            if (selectorExpression == null)
                throw new ArgumentNullException("selectorExpression");
            MemberExpression body = selectorExpression.Body as MemberExpression;
            if (body == null)
                throw new ArgumentException("The body must be a member expression");
           RaisePropertyChanged(body.Member.Name);            
        }

        /// <summary>
        /// Sets the field and notifies property changed
        /// </summary>
        protected bool SetField<T>(ref T field, T value, Expression<Func<T>> selectorExpression)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) return false;
            field = value;
            RaisePropertyChanged(selectorExpression);
            return true;
        }

        /// <summary>
        /// Returns the key of this client's storage - complete class name
        /// </summary>
        public string Key
        {
            get { return this.GetType().FullName; }
        }

        /// <summary>
        /// Protected method for loading state of viewmodel
        /// </summary>
        public virtual void LoadState(ClientStorage storage)
        {
        }

        /// <summary>
        /// Protected method for saving state of viewmodel
        /// </summary>
        public virtual void SaveState(ClientStorage storage)
        {
        }
    }
}
